﻿
using Aspose.Cells;
using HualongExcel.Classes;
using HualongExcel.Enum;
using HualongExcel.Utilities;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Drawing.Printing;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace HualongExcel
{
    internal class Common
    {
        private static Microsoft.Office.Interop.Excel.Application _curentExcelApp;

        public static Microsoft.Office.Interop.Excel.Application CurrentExcelApp
        {
            get
            {

                if (_curentExcelApp == null)
                {
                    _curentExcelApp = Globals.HualongExcel.Application;
                }
                return _curentExcelApp;
            }
        }

        /// <summary>
        /// 当前选中的范围
        /// </summary>
        public static Microsoft.Office.Interop.Excel.Range CurrentSelectedRange => Common.CurrentExcelApp.Selection;

        /// <summary>
        /// 当前选中的行
        /// </summary>
        public static int SelectedRow => CurrentSelectedRange.Row;

        /// <summary>
        ///  当前选中的行数
        /// </summary>
        public static int SelectedRowCount => Common.CurrentSelectedRange.Rows.Count;

        /// <summary>
        /// 当前选中的列
        /// </summary>
        public static int SelectedColumn => CurrentSelectedRange.Column;

        /// <summary>
        /// 当前选中的列数
        /// </summary>
        public static int SelectedColumnCount => Common.CurrentSelectedRange.Columns.Count;


        private static string worktemplatePathIns;
        public static string WorktemplatePath
        {
            get { return worktemplatePathIns; }
            set
            {
                worktemplatePathIns = value;
                worktemplateDataIns = TemplateHelper.Loadtemplate(WorktemplatePath);
            }
        }

        private static templateData worktemplateDataIns;

        public static ReplaceType SelectedReplaceType;

        public static templateData WorktemplateData
        {
            get
            {

                if (worktemplateDataIns == null)
                    worktemplateDataIns = TemplateHelper.Loadtemplate(WorktemplatePath);
                return worktemplateDataIns;
            }
        }


        static Spire.Xls.Workbook templateExcel;

        static Spire.Xls.Workbook TemplateExcel
        {
            get {
                if (templateExcel == null)
                {
                    templateExcel = new Spire.Xls.Workbook();
                    templateExcel.LoadTemplateFromFile(WorktemplateData.templatePath);
                }
                    
                return templateExcel;
            }
        }

        public static int GenerateCount { get; set; }



        private static string[] savedPathListCache;



        /// <summary>
        /// 拷贝文件
        /// </summary>
        /// <param name="sourceName">源文件路径</param>
        /// <param name="targetPath">目标路径（目标文件）</param>
        public static void CopyToFile(string sourceName, string targetPath)
        {

            //Copy到新文件下
            FileInfo file = new FileInfo(sourceName);
            if (file.Exists)
            {
                //true 为覆盖已存在的同名文件，false 为不覆盖
                file.CopyTo(targetPath, true);
            }
        }


 

        #region 生成表格方法
        /// <summary>
        ///  使用模板生成表格
        /// </summary>
        /// <param name="template"></param>
        public static void GenerateSheetWithTemplate(templateData template)
        {

            if (string.IsNullOrWhiteSpace(template.templatePath))
            {
                System.Windows.Forms.MessageBox.Show("模板Excel表格为空，无法根据模板表格进行生成操作");
                return;
            }

            SaveFileDialog dialog = new SaveFileDialog();
            dialog.Title = "请选择要保存的位置以及文件名";
            dialog.Filter = "Excel文件(*.xlsx)|*.xlsx";
            dialog.FileName = template.namedRule.ReplaceVariable();


            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                Thread saveTableThread = new Thread(() => GenerateSheet(dialog.FileName,Common.SelectedRow,Common.SelectedColumn));
                saveTableThread.IsBackground = true;
                saveTableThread.Start();
                SaveGenerateCount();
            }
        }

        public static void GenerateSheetsWithTemplate(templateData template)
        {

            FolderBrowserDialog folder = new FolderBrowserDialog();  //查找文件夹中
            folder.Description = "请选择保存的文件夹路径";
            if (folder.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string path = folder.SelectedPath; //文件夹路径
                int count = 0;
                //int start = 0;
                switch (Common.SelectedReplaceType)
                {
                    case ReplaceType.WithRow://跟随当前行
                        count = Common.SelectedRowCount;
                        //start = Common.SelectedRow;
                        break;
                    case ReplaceType.WithColumn://跟随当前列
                        count = Common.SelectedColumnCount;
                        //start = Common.SelectedColumn;
                        break;
                }

                Thread saveTableThread = new Thread(() => GenerateSheets(template, path, Common.SelectedRow, Common.SelectedColumn,count));
                saveTableThread.IsBackground = true;
                saveTableThread.Start();
            }
        }


        private static void GenerateSheet(string savePath,int row,int column)
        {
            Spire.Xls.Worksheet sheet = TemplateExcel.Worksheets[0];

            MappingSheet(sheet, row, column);
            TemplateExcel.SaveToFile(savePath);
            //Task saveTask= TemplateExcel.SaveToFile(savePath);
            //Task.WaitAll(saveTask);
            Common.GenerateCount++;
        }

        private static void GenerateSheets(templateData template, string rootPath, int row, int column, int targetCount)
        {
            savedPathListCache=new string[targetCount];
            for (int i = 0; i < targetCount; i++)
            {
                savedPathListCache[i] = $@"{rootPath}\{template.namedRule.ReplaceVariable()}.xlsx";
                Task thread1 = Task.Factory.StartNew(() => GenerateSheet(savedPathListCache[i], row + i, column + i));
                Task.WaitAll(thread1);
               
            }
            SaveGenerateCount();
        }

        public static void MappingSheet(Spire.Xls.Worksheet sheet,int row,int Column)
        {
            //Microsoft.Office.Interop.Excel.Application app = ExcelHelper.OpenWorkbook(dialog.FileName, true);



            foreach (var pair in Common.WorktemplateData.mapping)
            {


                var targetAddress = pair.Value.Replace("$", String.Empty);


                var pattern = @"\{(.*?)\}";
                var match = Regex.Match(pair.Key, pattern);//匹配{}
                if (match.Success)//如果匹配成功，则说明映射的是变量
                {
                    sheet.Range[targetAddress].Value=(pair.Key.ReplaceVariable());
                    continue;
                }

                string source_address = pair.Key;


                var ColumnStartIndex = source_address.IndexOf("$");
                var RowStartIndex = source_address.LastIndexOf("$");


                var Column_Address = source_address.Substring(ColumnStartIndex + 1, RowStartIndex - 1);
                var Row_Address = source_address.Substring(RowStartIndex + 1);



                switch (Common.SelectedReplaceType)
                {
                    case ReplaceType.WithRow://跟随当前行
                        Row_Address = row.ToString();
                        break;
                    case ReplaceType.WithColumn://跟随当前列
                        Column_Address = Column.ToName();
                        break;
                }



                source_address = $"{Column_Address}{Row_Address}";
                string contentValue = Convert.ToString(Common.CurrentExcelApp.Range[source_address].Value);

                sheet.Range[targetAddress].Value=(contentValue.ReplaceVariable());//映射的值为当前单元格内容替
            }

   

        }

        /// <summary>
        /// 保存生成数量
        /// </summary>
        public static void SaveGenerateCount()
        {
            SaveHelper.SetData(RibbonConstant.GenerateCount.ToString(), GenerateCount);
        }

        /// <summary>
        ///  加载生成数量
        /// </summary>
        public static void LoadGenerateCount()
        {
            GenerateCount = (int)SaveHelper.GetData(RibbonConstant.GenerateCount.ToString(), 0);
        }



        #endregion


        #region  打印表格方法


        public static void PrintSheetsWithTemplate(PrinterSettings printerSettings)
        {
            if (printerSettings is null)
            {
                throw new ArgumentNullException(nameof(printerSettings));
            }

            Thread saveTableThread = new Thread(() => PrintSheets(printerSettings));
            saveTableThread.IsBackground = true;
            saveTableThread.Start();
        }


        public static void PrintSheets(PrinterSettings settings)
        {

            //静默打印Excel文档
         
      
            //workbook.PrintDocument.PrintController = new StandardPrintController();
            MessageBox.Show($"{settings.PrinterName}正在打印\n总计打印{savedPathListCache.Length}个表格");
            for (int i = 0; i < savedPathListCache.Length; i++)
            {
                //加载Excel文档
                Spire.Xls.Workbook workbook = new Spire.Xls.Workbook();
                workbook.LoadFromFile(@savedPathListCache[i]);
                workbook.PrintDocument.PrinterSettings = settings;
                //MessageBox.Show($"正在打印：\n{@savedPathListCache[i]}");
                workbook.PrintDocument.Print();
                
            }

            MessageBox.Show("打印完成");

        }


        #endregion

    }
}
